package com.qinyunkj.searchchatserver.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qinyunkj.searchchatserver.config.ChatGPTConfig;
import com.qinyunkj.searchchatserver.model.dto.ArticleAnalysis;
import com.qinyunkj.searchchatserver.model.entity.ArticleQA;
import com.qinyunkj.searchchatserver.service.ChatGPTService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@RequiredArgsConstructor
public class ChatGPTServiceImpl implements ChatGPTService {

    private final ChatGPTConfig config;
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    @Override
    public ArticleAnalysis analyzeArticle(String title, String content) {
        String prompt = String.format("""
            请分析以下文章的内容，提取合适的分类和标签。
            要求：
            1. 分类只能有一个
            2. 标签最多5个，用逗号分隔
            3. 只返回JSON格式数据，包含category和tags两个字段
            
            文章标题：%s
            文章内容：%s
            """, title, content);

        String response = callChatGPT(prompt);
        try {
            return objectMapper.readValue(response, ArticleAnalysis.class);
        } catch (Exception e) {
            log.error("Parse ChatGPT response failed", e);
            throw new RuntimeException("分析文章失败");
        }
    }

    @Override
    public List<ArticleQA> generateQA(String title, String content, int count) {
        String prompt = String.format("""
            基于以下文章内容，分别生成两种场景的对话，每种场景生��%d个对话（总共%d个）。
            
            要求：
            1. 对话要完全基于文章内容，使用文章中的真实案例
            2. 分两种场景，每种场景必须生成%d个对话：
               - 热恋中(IN_LOVE)：情侣吵架时的对话，女生表现出不满和抱怨
               - 追求中(PURSUING)：被拒绝或被拉黑时的场景，女生表现出冷漠和攻击性
            3. 女生的语气特点：
               - 热恋场景下：充满抱怨、指责和不满，如"你就知道..."、"你从来都不..."、"你根本就不..."
               - 追求场景下：冷漠、反感、带有攻击性，如"烦死了"、"你是不是有病"、"别再来烦我了"
               - 可以使用省略号表示情绪、添加语气词如"呵呵"、"啧"等
            4. 男生的回应特点：
               - 热恋场景下：
                  * 要有哄人的语气，如"宝宝别生气了"、"乖，我错了"
                  * 带有撒娇和示弱的口吻，如"你要是不理我我可怎么办啊"
                  * 承认错误并表达感情，如"我就是太在意你了"
               - 追求场景下：
                  * 表达真诚和在意，如"我是真的很喜欢你"
                  * 带点可怜和委屈，如"让我做��么都行"
                  * 适当示弱，如"你不理我我真的很难受"
               - 避免过于正式的客套话，要有感情和温度
            5. 返回格式为JSON数组，每个元素包含：
               - question: 女生的抱怨或攻击性言论
               - answer: 男生哄人的回应
               - sceneType: 场景类型（IN_LOVE或PURSUING）
            6. 返回的数组必须包含：
               - %d个热恋场景(IN_LOVE)的对话
               - %d个追求场景(PURSUING)的对话
            
            示例格式：
            [
                {
                    "question": "呵呵，你就知道工作，工作，工作！我在你眼里就没有一点位置是吗？烦死了...",
                    "answer": "宝宝别生气了好不好~我这不是想给你更好的生活嘛，你要是再不理我，我今晚就睡不着觉了，我错了还不行吗...",
                    "sceneType": "IN_LOVE"
                },
                {
                    "question": "你是不是有病啊？都说了别找我了，看到你的消息就烦，赶紧爬开！",
                    "answer": "我知道我很烦人，但我是真的很喜欢你...你让我做什么都行，就是别把我拉黑好不好，我真的会很难受...",
                    "sceneType": "PURSUING"
                }
            ]
            
            文章标题：%s
            文章内容：%s
            """, count, count * 2, count, count, count, title, content);

        String response = callChatGPT(prompt);
        try {
            // 提取JSON内容
            String jsonContent = extractJsonContent(response);
            List<ArticleQA> qaList = objectMapper.readValue(jsonContent,
                objectMapper.getTypeFactory().constructCollectionType(List.class, ArticleQA.class));

            // 验证每种场景的数量是否正确
            long inLoveCount = qaList.stream().filter(qa -> "IN_LOVE".equals(qa.getSceneType())).count();
            long pursuingCount = qaList.stream().filter(qa -> "PURSUING".equals(qa.getSceneType())).count();

            return qaList;
        } catch (Exception e) {
            log.error("Parse ChatGPT response failed, response: {}", response, e);
            throw new RuntimeException("生成问答失败");
        }
    }

    /**
     * 从ChatGPT响应中提取JSON内容
     */
    private String extractJsonContent(String response) {
        // 1. 尝试查找第一个 '[' 和最后一个 ']'
        int startIndex = response.indexOf('[');
        int endIndex = response.lastIndexOf(']');

        if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
            // 找到了完整的JSON数组
            return response.substring(startIndex, endIndex + 1);
        }

        // 2. 如果没找到数组，尝试使用正则表达式匹配JSON对象数组
        String regex = "\\[\\s*\\{[^\\[\\]]*\\}(\\s*,\\s*\\{[^\\[\\]]*\\})*\\s*\\]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(response);

        if (matcher.find()) {
            return matcher.group();
        }

        // 3. 尝试提取所有JSON对象并组合成数组
        regex = "\\{[^\\{\\}]*\\}";
        pattern = Pattern.compile(regex);
        matcher = pattern.matcher(response);

        StringBuilder jsonArray = new StringBuilder("[");
        boolean first = true;

        while (matcher.find()) {
            if (!first) {
                jsonArray.append(",");
            }
            jsonArray.append(matcher.group());
            first = false;
        }
        jsonArray.append("]");

        if (jsonArray.length() > 2) { // 不只是"[]"
            return jsonArray.toString();
        }

        // 4. 如果还是无法提取，尝试清理和修复JSON格式
        String cleaned = response
            .replaceAll("(?s)```json\\s*|```\\s*", "") // 移除Markdown代码块标记
            .replaceAll("(?m)^\\s*//.*$", "") // 移除注释
            .replaceAll("[\\r\\n\\t]", "") // 移除换行和制表符
            .trim();

        // 确保以 [ 开始，以 ] 结束
        if (!cleaned.startsWith("[")) {
            cleaned = "[" + cleaned;
        }
        if (!cleaned.endsWith("]")) {
            cleaned = cleaned + "]";
        }

        // 修复可能的JSON格式问题
        cleaned = cleaned
            .replaceAll("\\}\\s*\\{", "},{") // 修复对象之间的分隔
            .replaceAll("\\]\\s*\\[", "],[") // 修复数组之间的分隔
            .replaceAll(",\\s*]", "]") // 移除最后多余的逗号
            .replaceAll("\\[\\s*,", "[") // 移除开始多余的逗号
            .replaceAll("\\{\\s*,", "{") // 修复对象开始的格式
            .replaceAll(",\\s*\\}", "}"); // 修复对象结束的格式

        log.debug("Cleaned JSON content: {}", cleaned);
        return cleaned;
    }

    private String callChatGPT(String prompt) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(config.getApiKey());

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", config.getModel());
        requestBody.put("messages", Arrays.asList(
            Map.of("role", "user", "content", prompt)
        ));
        requestBody.put("temperature", config.getTemperature());
        requestBody.put("max_tokens", config.getMaxTokens());

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

        try {
            ResponseEntity<Map> response = restTemplate.postForEntity(
                config.getApiUrl(), request, Map.class);

            List<Map<String, Object>> choices = (List<Map<String, Object>>) response.getBody().get("choices");
            Map<String, Object> message = (Map<String, Object>) choices.get(0).get("message");
            return (String) message.get("content");
        } catch (Exception e) {
            log.error("Call ChatGPT API failed", e);
            throw new RuntimeException("调用ChatGPT服务失败");
        }
    }
}
